package com.douma.lock;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

import java.util.ArrayList;
import java.util.List;

/**
 * 抖码课堂，专注中国程序员基础内功修炼
 * 官网：douma-tech.com
 * 公众号：抖码课堂
 *
 * @作者 : 老汤
 */
public class RedisDistributeLock6 {
    private Jedis jedis;

    private String uuid;

    public RedisDistributeLock6(String uuid, Jedis jedis) {
        this.uuid = uuid;
        this.jedis = jedis;
    }

    // SETNX state 1
    public boolean lock(int leaseTime) {
        // 如果 state 已经存在，则返回 0，说明加锁失败
        // 如果 state 不存在，则设置 state，返回 1，说明加锁成功
        //long state = jedis.setnx("state", "1");
        //jedis.expire("state", leaseTime);

        // SET state 1 NX EX 30
        // 唯一标识客户端的当前线程
        String id = uuid + ":" + Thread.currentThread().getId();
        SetParams setParams = new SetParams();
        setParams.nx();
        setParams.ex(leaseTime);
        String state = jedis.set("state", id, setParams);
        return state != null;
    }

    // 释放锁，删除 state
    public void unlock() {
        long threadId = Thread.currentThread().getId();
        List<String> args = new ArrayList<>();
        args.add(uuid + ":" + threadId); // 唯一标识客户端的当前线程
        jedis.eval(
                "if redis.call('get', 'state') == ARGV[1] then " +
                        "return redis.call('del', 'state') " +
                        "else return 0 " +
                        "end"
                , new ArrayList<>(), args);
    }
}
